<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>原生JS实现购物车结算功能代码</title>
    <link rel="stylesheet" href="../css/style.css" />
    <script src="../js/vue.js"></script>
</head>

<body>
    <div id="app">
        <div class="catbox">
            <table id="cartTable">
                <thead>
                    <tr>
                        <th><label>
                                <input class="check-all check" type="checkbox"
                                    v-model="checkAll" />&nbsp;&nbsp;全选</label></th>
                        <th>商品</th>
                        <th>单价</th>
                        <th>数量</th>
                        <th>小计</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-for="(item,index) in list" :key="item.goodsId">
                        <td class="checkbox">
                            <input class="check-one check" v-model="item.isChecked" type="checkbox" />
                            {{item.isChecked?'选中':'未选中'}}
                        </td>
                        <td class="goods"><img :src="item.goodsImg" alt="" /><span>{{item.goodsName}}</span></td>
                        <td class="price">{{item.goodsPrice}}</td>
                        <td class="count">
                            <span class="reduce" :style="{cursor:item.buyNum > 1 ? 'pointer':'not-allowed'}"
                                @click="reduceHandler(item)">{{item.buyNum > 1 ? '-': ''}}</span>
                            <input class="count-input" type="text" :value="item.buyNum" />
                            <span class="add" @click="addHandler(item)">+</span>
                        </td>
                        <td class="subtotal">{{(item.goodsPrice*item.buyNum).toFixed(2)}}</td>
                        <td class="operation"><span class="delete" @click="deleteOneHandler(item)">删除</span></td>
                    </tr>
                </tbody>
            </table>
            <div class="foot" id="foot">

                <a class="fl" id="deleteAll" @click="deleteAllHandler" href="javascript:;">删除</a>
                <div class="fr closing" onclick="getTotal();">结 算</div>
                <input type="hidden" id="cartTotalPrice" />
                <div class="fr total">合计：￥<span id="priceTotal">{{priceTotal}}</span></div>
                <div class="fr selected" id="selected">已选商品<span id="selectedTotal">{{selectedTotal}}</span>件<span
                        class="arrow up">︽</span><span class="arrow down">︾</span></div>
                <div class="selected-view">
                    <div id="selectedViewList" class="clearfix">
                        <div><img src="../images/1.jpg"><span>取消选择</span></div>
                    </div>
                    <span class="arrow">◆<span>◆</span></span>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    var vm = new Vue({
        el: "#app",
        data: {
            list: [],
        },
        methods: {
            getData() {
                var xhr = new XMLHttpRequest();
                xhr.open("get", "../data/shoppingCar.json", true);
                xhr.send();
                xhr.onreadystatechange = () => {
                    if (xhr.readyState == 4 && xhr.status == 200) {
                        var res = JSON.parse(xhr.responseText);
                        console.log("数据请求成功", res);
                        this.list = res;


                        // 有时候需要给请求过来的数据的对象中新增属性

                        // this.list.forEach(item=>item.isChecked = false);  // 给Vue中的数组对象中的对象数据新增属性 => 此写法不能被Vue响应式拦截到(不会触发视图更新)

                        this.list.forEach(item => Vue.set(item, "isChecked", false));  // 给Vue中的数组对象 中的对象数据新增属性 => 此写法能被Vue响应式拦截到

                        // console.log(this);
                    }
                }
            },
            addHandler(item) {
                item.buyNum++;
            },
            reduceHandler(item) {
                if (item.buyNum <= 1) return false;
                item.buyNum--;
            },
            deleteOneHandler(item) {
                var index = this.list.findIndex(v => v === item);
                this.list.splice(index, 1);
            },
            deleteAllHandler() {
                // 全删 -> 删除所有选中状态的商品 
                // 分析: 把所有选中状态的商品删除 => 剩余就是未被选中状态的商品

                var arr = this.list.filter(v => v.isChecked == false); // 找到所有为未选中的
                this.list = arr;

            }
        },
        computed: {
            // 全选状态 
            // 1. 全选状态取值: 依赖于所有的单选-> 所有的单选全部被选中,全选也会被选中, 否则就不选中
            // 2. 全选状态赋值: 所有单选框的状态跟随全选的状态
            checkAll: {
                get: function () {
                    // 单击单选 -> isChecked更新 -> this.list更新 -> checkAll更新
                    var flag = this.list.every(item => item.isChecked);  // (every方法有bug -> []的任何判断都为true => 假设法(假设都存在-> 遍历数组找一个不存在的元素-> []不会遍历 -> true))
                    return this.list.length > 0 ? flag : false;  // 有商品就使用flag,没有商品默认false
                },
                set: function (val) {
                    console.log(val);
                    this.list.forEach(item => item.isChecked = val);
                }
            },
            selectedTotal: function () {
                // var sum = 0;
                // this.list.forEach(v=>{
                //     if(v.isChecked){
                //         sum += v.buyNum;
                //     }
                // })
                // return sum;

                // return this.list.reduce((prev, item) => {
                //     return item.isChecked ? prev + item.buyNum : prev;
                // }, 0);

                // return this.list.reduce((prev,item)=>item.isChecked? prev + item.buyNum : prev,0);

                return this.list.reduce((prev, { isChecked, buyNum }) => isChecked ? prev + buyNum : prev, 0);
            },
            priceTotal:function(){
                return this.list.reduce((prev, { isChecked, buyNum, goodsPrice }) => isChecked ? prev + (buyNum*goodsPrice) : prev, 0).toFixed(2);
            }
        },
        watch: {

        },
        /*  beforeCreate() {
             console.log(1);
         },
         created() {
             console.log(2);
         },
         beforeMount() {
             console.log(3);
         }, */
        mounted: function () {
            // console.log(4);
            this.getData();
        }
    })


</script>

</html>